﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.Serialization;
using System.Web.UI.HtmlControls;
using System.Reflection;

namespace Webcoda.SP.WP.Toolparts {

    /// <summary>
    /// Description of the toolpart. Override the GetToolParts method
    /// in your Web Part class to invoke this toolpart. To establish
    /// a reference to the Web Part the user has selected, use the
    /// ParentToolPane.SelectedWebPart property.
    /// </summary>
    public class XslToolPart : Microsoft.SharePoint.WebPartPages.ToolPart {

        // an event handler for the Init event
        private void ToolPart1_Init(object sender, System.EventArgs e) {

        }

        /// <summary>
        /// Constructor for the class. A great place to set Set
        /// default values for additional base class properties
        /// here.
        /// <summary>
        public XslToolPart() {
            // Set default properties
            this.Title = "Custom Xsl";
            this.Init += new EventHandler(ToolPart1_Init);
        }

        ///	<summary>
        ///	Called by the tool pane to apply property changes to
        /// the selected Web Part.
        ///	</summary>
        public override void ApplyChanges() {
            WebPart wp1 = this.ParentToolPane.SelectedWebPart;

            // Send the custom text to the Web Part.
            SetPropertyValue(wp1, "Xsl", uiTxtXsl.Text);
            //SetPropertyValue(wp1, "ItemCssClass", uiTxtItemCssClass.Text);
        }

        /// <summary>
        ///	If the ApplyChanges method succeeds, this method is
        /// called by the tool pane to refresh the specified
        /// property values in the toolpart user interface.
        /// </summary>
        public override void SyncChanges() {
            // sync with the new property changes here
        }

        /// <summary>
        ///	Called by the tool pane if the user discards changes
        /// to the selected Web Part.
        /// </summary>
        public override void CancelChanges() {
        }

        /// <summary>
        /// Render this Tool part to the output parameter
        /// specified.
        /// </summary>
        /// <param name="output">
        /// The HTML writer to write out to
        /// </param>
        protected override void RenderToolPart(HtmlTextWriter output) {
            
            // Establish a reference to the Web Part.
            WebPart parent = this.ParentToolPane.SelectedWebPart;

            output.Write(@"<script type='text/javascript'>

                                $(document).ready(function(){$('#uiDivRawXml').hide();});                                

                                function ToggleRawXML(){
                                    if($('#uiDivRawXml').css('display') == 'none'){
                                        $('#uiDivRawXml').show('normal');
                                        $('#uiLnkShowRawXml').html('Hide Raw Xml');
                                    }else{
                                        $('#uiDivRawXml').hide('normal');
                                        $('#uiLnkShowRawXml').html('Show Raw Xml');
                                    }
                                    return false;
                                }
                        </script>");

            uiPnlTools.RenderControl(output);
            output.Write("<div class='ms-ToolPartSpacing'></div>");
            output.Write("<a id='uiLnkShowRawXml' style='padding:0 10px 0 10px;' onclick='ToggleRawXML();return false;' href='javascript:void();'>Show Raw XML</a>");
            output.Write("<div class='ms-ToolPartSpacing'></div>");
            uiDivRawXml.RenderControl(output);
            output.Write("</div>");

            uiTxtXsl.Text = (string)GetPropertyValue(parent, "Xsl");
        }

        private Panel uiPnlTools;
        private Label uiLblXsl;
        private TextBox uiTxtXsl;
        private Literal uiLitNewLine;
        private Literal uiLitAreaRawXmlOpen;
        private Literal uiLitAreaRawXmlClose;
        protected Panel uiDivRawXml;
        protected Label uiLblRawXml;
        //protected Literal uiLitSpacer1;
        //protected Literal uiLitSpacer2;
        //protected Label uiLblItemCssClass;
        //protected TextBox uiTxtItemCssClass;
        protected internal Literal uiLitRawXml = new Literal();
        protected override void CreateChildControls() {
            WebPart parent = this.ParentToolPane.SelectedWebPart;

            //create ToolParts Panel
            uiPnlTools = new Panel();
            uiPnlTools.Attributes.Add("style", "padding:10px;");


            //create Xsl Label
            uiLblXsl = new Label();
            //uiLblXsl.Width = Unit.Percentage(100);
            uiLblXsl.Text = "Enter your custom XSL here:";
            uiPnlTools.Controls.Add(uiLblXsl);

            //create new line (<br/>) literal
            uiLitNewLine = new Literal();
            uiLitNewLine.Text = "<br />";
            uiPnlTools.Controls.Add(uiLitNewLine);

            //create Xsl TextBox
            uiTxtXsl = new TextBox();
            uiTxtXsl.TextMode = TextBoxMode.MultiLine;
            uiTxtXsl.Rows = 8;
            //uiTxtXsl.Width = Unit.Percentage(100);
            uiTxtXsl.Text = (string)GetPropertyValue(parent, "Xsl");
            uiTxtXsl.Attributes.Add("ms-tlpnwiden", "true");
            uiTxtXsl.Style.Add(HtmlTextWriterStyle.Width, "176px");
            uiPnlTools.Controls.Add(uiTxtXsl);

            //uiLitSpacer1 = new Literal();
            //uiLitSpacer1.Text = "<br/><br/><b>Item CSS Class</b><br/>";
            //uiPnlTools.Controls.Add(uiLitSpacer1);

            //uiLblItemCssClass = new Label();
            //uiLblItemCssClass.Text = "If you are creating custom XSL, you will need to give each item to be rotated the same CSS class. Please type the name of that class (can be a selector like 'div.item' or a class name like 'item') so that it can be used elsewhere:";
            //uiLblItemCssClass.Style.Add(HtmlTextWriterStyle.MarginTop, "8px");
            //uiPnlTools.Controls.Add(uiLblItemCssClass);

            //uiLitSpacer2 = new Literal();
            //uiLitSpacer2.Text = "<br/>";
            //uiPnlTools.Controls.Add(uiLitSpacer2);

            //uiTxtItemCssClass = new TextBox();
            //uiTxtItemCssClass.Text = (string)GetPropertyValue(parent, "ItemCssClass");
            //uiTxtItemCssClass.Attributes.Add("ms-tlpnwiden", "true");
            //uiTxtItemCssClass.Style.Add(HtmlTextWriterStyle.Width, "176px");
            //uiTxtItemCssClass.Style.Add(HtmlTextWriterStyle.MarginBottom, "8px");
            //uiPnlTools.Controls.Add(uiTxtItemCssClass);

            ///Create the Raw Xml Div tag in CreateChildControls
            ///so that it can be updated using callbacks.

            //create Raw Xml Div
            uiDivRawXml = new Panel();
            uiDivRawXml.ID = "uiDivRawXml";
            uiDivRawXml.Attributes.Add("style", "padding:0 10px 0 10px;display:none;");

            //create Raw Xml Label
            uiLblRawXml = new Label();
            uiLblRawXml.Text = "Raw XML:";
            this.uiDivRawXml.Controls.Add(uiLblRawXml);

            //create textarea open tag
            uiLitAreaRawXmlOpen = new Literal();
            uiLitAreaRawXmlOpen.Text = "<br/><textarea id='uiLitRawXml' rows='8' ms-tlpnwiden='true' style='width:176px;'>";
            this.uiDivRawXml.Controls.Add(uiLitAreaRawXmlOpen);

            //create Raw Xml Literal
            //uiLitRawXml = new Literal();
            uiLitRawXml.Text = "Loading...";
            this.uiDivRawXml.Controls.Add(uiLitRawXml);

            //create textarea close tag
            uiLitAreaRawXmlClose = new Literal();
            uiLitAreaRawXmlClose.Text = "</textarea>";
            this.uiDivRawXml.Controls.Add(uiLitAreaRawXmlClose);

            //add ToolParts Panel to ToolPart
            this.Controls.Add(uiPnlTools);

            base.CreateChildControls();
        }

        private string GetRawXml() {
            WebPart parent = this.ParentToolPane.SelectedWebPart;
            return (string)GetPropertyValue(parent, "Xml");
        }

        /// <summary>
        /// Sets a property value of an object by reflection.
        /// </summary>
        /// <param name="target">Target object.</param>
        /// <param name="name">Name of the property.</param>
        /// <param name="value">The value to set.</param>
        /// <returns>The property value.</returns>
        void SetPropertyValue(object target, string name, object value) {
            PropertyInfo pi = target.GetType().GetProperty(name);
            pi.SetValue(target, value, null);
        }

        /// <summary>
        /// Gets a property value of an object by reflection.
        /// </summary>
        /// <param name="target">Target object.</param>
        /// <param name="name">Name of the property.</param>
        /// <returns>The property value.</returns>
        object GetPropertyValue(object target, string name) {
            try {
                PropertyInfo pi = target.GetType().GetProperty(name);
                return pi.GetValue(target, null);
            } catch {
                return "##error##";
            }
        }

    }	
}
